//中缀表达式求值
#include <iostream>
#include <unordered_map>
#include <stack>
#include <string>
#include <cctype>
#include <functional>
using namespace std;
// 本质上跟后缀方法一致:操作数和操作符分别入栈 并且按先后顺序排列好,然后依次拿出运算即可
// 如果新来的操作符放不进去,就把原来的拿出来运算以后再放进去
// 1.遍历
// 遇到操作数入栈
// 遇到操作符判断优先级如果新的比栈顶的高则满足条件直接入栈
// 如果更低就不满足入栈条件,需要把高优先级的拿出来计算,计算结果入栈作为高优先级操作符的一个操作数
// 如果遇到左括号直接入栈,遇到右括号直接运算到左括号即可(括号里的运算顺序已经在遍历时整理好),最后再把左括号出栈,结果入栈
// 2.遍历后高优先级的操作符都在栈顶 依次计算即可
unordered_map<char, int> op_map{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
unordered_map<char, function<int(int, int)>> fc{
    {'+', [](int a, int b)
     { return a + b; }},
    {'-', [](int a, int b)
     { return a - b; }},
    {'*', [](int a, int b)
     { return a * b; }},
    {'/', [](int a, int b)
     { return a / b; }}};
stack<int> nums;
stack<char> ops;
void evl()
{
    int a, b;
    char op;
    int res;
    b = nums.top();
    nums.pop();
    a = nums.top();
    nums.pop();
    op = ops.top();
    ops.pop();
    res = fc[op](a, b);
    nums.push(res);
}
int main()
{
    string str;
    cin >> str;
    for (int i = 0; i < str.size(); i++)
    {
        char e = str[i];
        if (isdigit(e))
        {
            int x = 0;
            int j;
            for (j = i; j < str.size() && isdigit(str[j]); j++)
                x = x * 10 + str[j] - '0';
            i = --j;
            nums.push(x);
        }
        else if (e == '(')
        {
            ops.push(e);
        }
        else if (e == ')')
        {
            for (char op = ops.top(); op != '('; op = ops.top())
            {
                evl();
            }
            ops.pop();
        }
        else
        {
            // 栈为空或优先级更高就可以直接入栈
            while (!(ops.empty() || op_map[e] > op_map[ops.top()]))
            {
                evl();
            }
            ops.push(e);
        }
    }
    while (!ops.empty())
    {
        evl();
    }
    cout << nums.top();
    return 0;
}